<!--
 * @Author: lihaogn
 * @Date: 2023-08-05 16:09:27
 * @LastEditTime: 2023-08-07 23:50:43
 * @LastEditor: lihaogn
 * @Description: 
 * @FilePath: \lix-css-demo\瀑布流布局\js实现瀑布流.html
-->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      margin: 0;
      padding: 0;
    }

    .container {
      position: relative;
    }

    .item {
      background-color: #ccc;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
  </div>

  <script>
    class Waterfall {
      constructor(options) {
        this.$el = null;             // 父容器
        this.count = 4;              // 列数
        this.gap = 10;               // 间距
        Object.assign(this, options);
        this.width = 0;              // 列的宽度
        this.items = [];             // 子元素集合
        this.H = [];                 // 存储每列的高度，方便计算
        this.frag = null;            // 虚拟节点集合
        this.init();
      }

      init() {
        this.items = Array.from(this.$el.children);
        this.reset();
        this.render();
      }

      reset() {
        this.frag = document.createDocumentFragment();
        this.width = this.$el.clientWidth / this.count;
        this.H = new Array(this.count).fill(0);
      }

      render() {
        const { width, items, frag, H, gap } = this;

        items.forEach((item, index) => {
          item.style.width = width + "px";
          item.style.height = index % 2 === 0 ? '100px' : '200px'
          item.style.position = "absolute";

          let tag = H.indexOf(Math.min(...H)); // 每次取高度最小的一列
          // item.style.left = tag * (width + gap) + "px";
          // item.style.top = H[tag] + "px";
          item.style.transform = `translate(${tag * (width + gap)}px,${H[tag]}px)` // 代替上面两行，减少了回流的步骤
          H[tag] += item.clientHeight + gap;
          frag.appendChild(item);

          // let img = item.querySelector("img");
          // if (img.complete) {
          //   let tag = H.indexOf(Math.min(...H));
          //   item.style.left = tag * (width + gap) + "px";
          //   item.style.top = H[tag] + "px";
          //   H[tag] += img.height * width / img.width + gap; // 图片高度等比例缩放
          //   frag.appendChild(item);
          // }
          // else {
          //   img.addEventListener("load", () => {
          //     let tag = H.indexOf(Math.min(...H));
          //     item.style.left = tag * (width + gap) + "px";
          //     item.style.top = H[tag] + "px";
          //     H[tag] += img.height * width / img.width + gap;
          //     frag.appendChild(item);
          //     this.$el.append(frag);
          //   })
          // }
        })
        this.$el.append(frag);
      }
    }

    window.onload = new Waterfall({
      $el: document.querySelector('.container'),
      count: 4,
      gap: 12
    })
  </script>

</body>

</html>